// Help functions 

function waiting_block(selector, callback, cont = document.querySelector('html')) {
    let node = document.querySelector(selector);
    if (node) {
        if (callback) { callback(node) } else { console.log(node) }
        return
    }
    const observer = new MutationObserver((mutationsList, observer) => {
        for (const mutation of mutationsList) {
            let node = document.querySelector(selector);
            if (node) {
                if (callback) { callback(node) } else { console.log(node) };
                observer.disconnect();
                break
            }
        }
    });
    observer.observe(cont, { childList: true, subtree: true });
}

async function goHeadRequest(url, timeout = 2000) {
    try {
        const response = await Promise.race([
            fetch(url, {
                method: 'HEAD'
            }),
            new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), timeout))
        ]);

        if (response.ok) {
            return response;
        } else {
            throw new Error('HTTP error ' + response.status);
        }
    } catch (error) {
        throw new Error('Error: ' + error.message);
    }
}

async function getDT() {
    let timeServers = [
        '/'
    ]
    let err;
    for (const url of timeServers) {
        try {
            // console.log('URL:' +url);
            const head_response = await goHeadRequest(url);
            const dt = new Date(head_response.headers.get('Date'));
            return dt;
        } catch (error) {
            console.warn(error);
            err = error;
        }
    }
    return new Date();
}

function run_events(events, currentDate = new Date()) {
    for (let event in events) {
        if (event === '-') continue;
        const [start, end] = event.split('|');
        let [startDay, startMonth] = start.split('-');
        let [endDay, endMonth] = end.split('-');

        startMonth = parseInt(startMonth, 10);
        endMonth = parseInt(endMonth, 10);

        let startYear = currentDate.getFullYear();
        let endYear = startYear;

        if (endMonth < startMonth) {
            startYear--; // Увеличиваем текущий год, если конечный месяц меньше начального
        }

        const startDate = new Date(startYear, startMonth - 1, startDay);
        const endDate = new Date(endYear, endMonth - 1, endDay);

        if (currentDate >= startDate && currentDate <= endDate) {
            events[event](event, currentDate);
        }
    }
}

/* Snow script */
async function snowInit(snowCollect = [], snowCont = 'body', snow_script_path = null, imgSrc = false) {
    if (typeof snowCollect === 'string') {
        document.querySelectorAll(snowCont).snowfall('clear');
        return
    }
    if (!snow_script_path) { console.error('Snow script path requred!'); return; }
    await loader.importJS(snow_script_path);
    if (getCookie('SnowScript') == 'OFF') return;
    snowCollect.forEach(e => {
        e = document.querySelector(e);
        e.style.position = 'relative';
        e.insertAdjacentHTML('beforeEnd', '<div class="snowLine" style="position:absolute;bottom:0;width:100%;height:20px"></div>');
    });
    document.querySelector(snowCont).snowfall({
        collection: '.snowLine',
        flakeIndex: 999,
        flakeCount: 10,
        minSize: 13,
        maxSize: 15,
        minSpeed: 1,
        maxSpeed: 2,
        collectionHeight: 20,
        flakeColor: '#ffffff00',
        round: false,
        image: imgSrc
        /*flakeCount: 50, // Количество снежинок
       flakeColor: '#e0e0ff', // Цвет снежинок
       flakeIndex: 999, // z-index снежинок
       minSize: 1, // Минимальный размер снежинки
       maxSize: 4, // Максимальный размер снежинки
       minSpeed: 1, // Минимальная скорость снежинки
       maxSpeed: 5, // Максимальная скорость снежинки
       round: true, // Закруглённые снежинки (true/false)
       shadow: true, // С тенью (true/false)
       collection: false, // Накапливаются ли снизу, образуя сугробы (false or selector)
       collectionHeight: 50, // Количество накапливаемого снега
       deviceorientation: true // Подстраиваться ли под устройство
       // Русификация от Apocalypse
       // apo-ucoz.com (c) 2013*/
    });
    console.log('Snow script init');
    // $('canvas[height=20]').css({ left: function (i, v) { return parseFloat(v) + 10 }, width: function (i, v) { return parseFloat(v) - 20 } });
}

async function cheats(staticURL) {
    function Random(min, max) {
        if (typeof (min) === 'number') { min = min } else { min = 1 };
        if (typeof (max) === 'number') { max = max } else { max = 10 };
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }
    let combo = {}, pA, MusicPl, alerts = { music: [] };
    const
        l = "ArrowLeft",//стрелка влево
        r = "ArrowRight",//стрелка вправо
        vn = "ArrowDown",//стрелка вниз
        vv = "ArrowUp",//стрелка вверх,
        d = "KeyD",//буква d
        i = "KeyI",//буква i
        t = "KeyT"
    const Cheats = {
        'Music': [1, l, r, vn, vn, vv, vv],
        'Snow Script': [1, l, l, r, r,],
        'UpToBoth': [1, vn, vv],
        'DII': [1, l, l, d, i, i],
        'NY': [1, vv, vv, vv]
        //'Test':[1,t,t]
    };//Имя чита : Вводится комбинация клавиш в keyCod'ах или определенных выше константах, при последовательном вводе которой произойдет действие. Нулевой элемент массива - счетчик.
    document.body.addEventListener("keyup", async function (e) {
        for (let k in Cheats) {
            let c = k;
            k = Cheats[k];
            if (k[k[0]] == e.code) {
                if (!combo[c]) combo[c] = []
                combo[c].push(e.key);
                console.log(combo);
                if (k[0] == k.length - 1) {
                    //Далее выполнение действий для введенной комбинации
                    switch (c) {
                        case 'NY':
                            console.log('Cheat ' + c + ' activated!');
                            let dt = new Date();
                            let ny = await newYear(
                                staticURL,
                                `${dt.getFullYear()}/${dt.getMonth()}/01`,
                                `${dt.getFullYear()}/${dt.getMonth() + 1}/${dt.getDate()} ${dt.getHours()}:${dt.getMinutes() + 3 < 60 ? dt.getMinutes() + 3 : '03'}`,
                                dt
                            );
                            if (typeof msg == 'function') {
                                msg(`Вы активировали секретный код: ${c}`, 999999, "", {
                                    onClose: () => { ny.stop(); }
                                });
                            }
                            break;
                        case 'DII':
                            console.log('Cheat ' + c + ' activated!');
                            let cont = document.querySelector('#root');
                            cont.insertAdjacentHTML('beforeBegin', `<video id="DIIRes" src="${staticURL}/video/dII.mp4" autoplay loop mute></video>
                            <style>
                            #DIIRes { position: fixed; width:100%; transition: all 1.5s ease-in; }
                            body { transition: all 1.4s; }
                            body::after {
                                content: "";
                                position: fixed;
                                top:0; left:0; width: 100%; height: 100%;
                                background: red;
                                opacity: 0;
                                z-index: 3;
                                transition: inherit;
                            }
                            #DIIRes.DIIRes-hide {
                                transform-origin: top;
                                transform: scale(4) translateY(195px)
                            }
                            body.DIIRes-hide::after {
                                opacity: 1;
                            }
                            </style>`);
                            let DII = document.querySelector('#DIIRes');
                            let d2m;
                            if (playSound) d2m = playSound(`${staticURL}/music/d2ost.mp3`);
                            cont.style.opacity = '0.2';
                            if (typeof msg == 'function') {
                                msg(`Вы активировали секретный код: ${c}`, 10000, "", {
                                    onClose: () => {
                                        document.querySelector('#DIIRes').classList.add('DIIRes-hide');
                                        document.body.classList.add('DIIRes-hide');
                                        setTimeout(() => {
                                            document.querySelector('#DIIRes').remove();
                                            document.querySelector('#root').style.opacity = 1;
                                            document.body.style.transition = "all .3s";
                                            document.querySelector('body').classList.remove('DIIRes-hide');
                                            d2m.pause();
                                        }, 1300);
                                    }
                                });
                            }
                            break;
                        case 'Music':
                            alerts.music = alerts.music.filter(alert => alert.isOpen);
                            alerts.music.forEach(alert => alert.close());
                            if (!pA) { pA = new Audio(); } else { pA.pause(); }
                            if (!pA.canPlayType('audio/mp3')) return;
                            console.log('Cheat ' + c + ' activated!');
                            if (!MusicPl) {
                                MusicPl = {
                                    1: ['Бетховен - Ангелы и Демоны', `${staticURL}/music/lvb_angels_and_demons.mp3`, 134],
                                    2: ['Бетховен - Соната для ф-но №14, часть 3', `${staticURL}/music/blv_sonata_14_presto_agitato.mp3`, 432],
                                    3: ['Вивальди Времена года - Лето', `${staticURL}/music/va_vremena_goda_leto.mp3`, 172],
                                    4: ['Вагнер Рихард - Полет валькирий из оперы «Валькирия»', `${staticURL}/music/vr_polet_valkiriy.mp3`, 326],
                                    5: ['Вивальди Антонио - Времена года. Весна', `${staticURL}/music/va_vremena_goda_vesna.mp3`, 204],
                                    6: ['Бетховен - Соната для ф-но №14, часть 1', `${staticURL}/music/blv_sonata_14_adagio_sostenuto`, 335]
                                }
                            }
                            let Rnd = Random(1, 5);
                            pA.src = MusicPl[Rnd][1];
                            pA.play();
                            if (typeof msg == 'function') {
                                msg(`Вы активировали секретный код: ${c}<br><i>Комбинация:<i><br>${combo[c].toString()}`);
                                alerts.music.push(msg(`Играет композиция:<br>${MusicPl[Rnd][0]}`, MusicPl[Rnd][2]));
                            }
                            break;

                        case 'Test':
                            console.log('Cheat ' + c + ' activated!');
                            console.log('И понял Антоха, что поступил плохо!');
                            if (typeof msg == 'function') msg(`Вы активировали секретный код: ${c}<br>И понял Антоха, что поступил плохо!`);
                            break;

                        case 'Snow Script':
                            let SnowScript = getCookie('SnowScript');
                            let date = new Date(new Date().getTime() + 7776000 * 1000);
                            if ((!SnowScript) || (SnowScript == 'ON')) { SnowScript = 'OFF'; } else if (SnowScript == 'OFF') { SnowScript = 'ON'; }
                            document.cookie = "SnowScript=" + SnowScript + "; path=/; SameSite=Strict; expires=" + date.toUTCString();
                            switch (SnowScript) {
                                case 'OFF':
                                    try { await snowInit('clear', '.site_header'); } catch (err) { return }
                                    if (typeof msg == 'function') msg(`Вы активировали секретный код: ${c}<br><i>Комбинация:<i><br>${combo[c].toString()}<br>
                                    Скрипт снега выключен.<br>Для включения повторите код.`);
                                    break;
                                case 'ON':
                                    try { snowInit(['.site_header'], '.site_header', `${staticURL}/js/snowfall.js`) } catch (err) { console.log(err) }
                                    if (typeof msg == 'function') msg(`Вы активировали секретный код: ${c}<br><i>Комбинация:<i><br>${combo[c].toString()}<br>
                                    Скрипт снега включен.<br>Для выключения повторите код.`);
                                    break;
                            }
                            break;
                        case 'UpToBoth':
                            if (typeof msg == 'function') msg(`Вы активировали секретный код: ${c}<br><i>Комбинация:<i><br>${combo[c].toString()}`);
                            let cDeg = parseInt(document.body.dataset.rotateX);
                            cDeg = isNaN(cDeg) || cDeg == 180 ? 0 : 180;
                            document.body.dataset.rotateX = cDeg;
                            document.body.animate([{ transform: `rotate3d(1,0,0,${cDeg}deg)` }], { duration: 500, fill: "forwards" });
                            // console.log(cDeg);
                            break;
                    }
                    k[0] = 1;
                    combo[c] = [];
                    break;
                }
                k[0] = k[0] + 1;
            } else {
                k[0] = 1;
                combo[c] = [];
            }
        }
    }, combo, pA, MusicPl, alerts);
    console.log('CheatCodes is loaded');
}

function document_viewer(staticURL) {
    function view() {
        // console.time('View_doc');
        if (this.hasAttribute('download')) return;

        // document.querySelector('.fCont').click();

        let layer = document.createElement('div');
        layer.className = 'fCont';
        layer.innerHTML = `<style>
            .fCont {opacity: 0; position: fixed; background: rgba(0,0,0,.5); width: 100%; height: 100%; margin: auto; left: 0; right: 0; top: 0; bottom: 0; z-index: 9999}
            .fCont > div {margin: auto; transition: .3s; height: 100%; width: 80%; position: absolute; top: 0; right: 0; bottom: 0; left: 0; padding: 0 1px 0 0; z-index: 1000; background: #FFF;margin-top: -100vh;}
            .frame-control-panel {position: absolute; background-color: rgba(147,147,147,0.7);}
            .frame-control-panel a {display: inline-block; width: 50px; height: 47px; line-height: 47px; text-align: center; font-size: 17px; font-weight: bold; text-decoration: none; color: rgba(255,255,255,.87); text-shadow: 0 1px 0 rgba(0,0,0,0.8);}
            .frame-control-panel a:hover {background: #838383; color: rgba(255,255,255,.87); cursor: default}
            .frame-control-panel a:nth-of-type(2) > div {background: url(${staticURL}/img/icons/doc_viewer/v-sprite19.svg) no-repeat 0 -2467px; background-origin: content-box; padding: 0px 0px 0 15px; margin-right: -15px;}
            </style>
            <div><div class='frame-control-panel'><a onclick="$('.fCont').trigger('click')">X</a><a href='${this.href}' download><div>&nbsp;</div></a></div>
            <iframe name='doc' src='' style='width:100%;height:100%;padding:0;margin:0'></iframe></div></div>`;

        let url = this.href;
        url = 'https://docs.google.com/viewerng/viewer?url=' + url + '&embedded=true';
        layer.querySelector('iframe').src = url;

        // document.body.scrollTo(0, 0);
        document.body.style.overflow = 'hidden';
        document.body.appendChild(layer);

        layer.querySelector('iframe').addEventListener('hover', function (event) { layer.querySelector('.frame-control-panel').animate([{ opacity: "1" }], { duration: 300, fill: "forwards" }) });
        layer.querySelector('iframe').addEventListener('mouseout', function (event) { layer.querySelector('.frame-control-panel').animate([{ opacity: "0" }], { duration: 1000, fill: "forwards" }) });
        setTimeout(() => document.querySelector('.frame-control-panel').animate([{ opacity: "0" }], { duration: 800, fill: "forwards" }), 3000);

        document.querySelector('.fCont iframe').addEventListener('load', () => console.log('frame loaded'));
        document.querySelector('.fCont').addEventListener('click', function (event) {
            if (event.target.closest('.frame-control-panel') || event.target.closest('iframe')) return
            document.querySelector('.fCont div').animate([{ marginTop: "100vh" }], { duration: 300, fill: "forwards" });
            setTimeout(() => {
                document.documentElement.style.overflow = 'auto';
                let layer = document.querySelector('.fCont');
                layer.style.display = 'none';
                layer.remove()
            }, 400);
        });

        layer.animate([{ opacity: "1" }], { duration: 500, fill: "forwards" });
        layer.querySelector('div').animate([{ marginTop: "15px" }], { delay: 500, duration: 500, fill: "forwards" });

        // console.timeEnd('View_doc');
        return false;
    }

    function isDocFileType(el) {
        const fileTypes = ['pdf', 'doc', 'docx', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'rtf'];
        if (el.href && fileTypes.includes(el.href.toLowerCase().split('.').pop())) return true;
        return false;
    }

    document.body.classList.add('doc-viewer');
    document.body.addEventListener('click', function (event) {
        event.preventDefault();
        let target = event.target.closest('a');
        if (target && target.tagName === 'A' && isDocFileType(target)) {
            view.call(target);
        }
    });
}

function salute(parent = "body", id = null, size = ['500px', '200px'], pos = [0, 0, 'auto', 'auto'], staticURL = '/') {
    document.querySelector(parent).insertAdjacentHTML('afterBegin', `
    <div id='${id}' class='event_salute' style='width:${size[0]};height:${size[1]};padding:0;margin:0;position:absolute;z-index:9999;left:;${pos[0]};top:${pos[1]};right:${pos[2]};bottom:${pos[3]};'>
        <img src='${staticURL}/img/saljut_prozrachnyj.gif' height='100%' width='100%'/>
    </div>`);
    return document.querySelector(`#${id}`);
}

async function newYear(staticURL = '/',
    startDate = `${(new Date()).getFullYear()}/11/01`,
    endDate = `${((new Date()).getFullYear() + 1)}/01/01`,
    currDate = new Date()) {
    let NewYearTimer = new DTimer({
        start: startDate,
        finish: endDate,
        relate: `${currDate.getFullYear()}/${currDate.getMonth() + 1}/${currDate.getDate()} ${currDate.getHours()}:${currDate.getMinutes()}:${currDate.getSeconds()}`//"2015/12/31 23:58:55"
    });
    let audio = null;
    let nye = {}
    let salutes = []

    nye.stop = function () {
        NewYearTimer.stop();
        if (audio) audio.stop();
        if (document.querySelector('.site_header__promo #timer-cont')) document.querySelector('.site_header__promo #timer-cont').remove();
        salutes.forEach(el => el.remove());
    }

    NewYearTimer.start(async function (date) {
        //update function
        let Y, M, d, h, m, s, postfix_d;
        //Y = this.fixTime(date.getYear());
        //M = this.fixTime(date.getMonth());
        d = this.fixTime(date.getDate());
        h = this.fixTime(date.getHours());
        m = this.fixTime(date.getMinutes());
        s = this.fixTime(date.getSeconds());
        d = d < 10 ? d.substr(1) : d;
        postfix_d = ['2', '3', '4'].includes(('' + d).slice(-1)) ? " дня " : d !== 11 && ('' + d).slice(-1) == 1 ? " день " : " дней ";
        document.querySelector('#timer-date').innerHTML = (d > 0 ? d + postfix_d : "") + h + ":" + m + ":" + s;
        if (date.getDate() == 0 && date.getHours() == 0 && date.getMinutes() < 1) {
            try {
                if (PlaySoundWebApi && !getCookie('ny_kuranty')) {
                    audio = await PlaySoundWebApi(`${staticURL}/music/kuranty.mp3`, 60 - date.getSeconds());
                    audio.play();
                }
            } catch (e) { };
            document.cookie = "ny_kuranty=play; path=/; SameSite=Strict; expires=" + date;
        }
    }, async function () {
        //end time function
        document.querySelector('#timer-date').animate({ 'opacity': '0' }, { duration: 3000, fill: "forwards" });
        msg(`<span style='text-align:center;font-size:25pt;font-family:Nautilus Pompilius'>Счастливого нового ${currDate.getFullYear() + 1} года</span>`, 999999, '', {
            onClose: () => { nye.stop() },
        });
        salutes.push(salute('body', 'sal1', ['45vw', 300], [0, 0, 'auto', 'auto'], staticURL));
        salutes.push(salute('body', 'sal2', ['45vw', 300], ['auto', 0, 0, 'auto'], staticURL));
        try {
            if (PlaySoundWebApi) {
                audio = await PlaySoundWebApi(`${staticURL}/music/gimn_rf.mp3`);
                audio.play();
            }
        } catch (e) { };
    });

    if (NewYearTimer.start !== 0) {
        if (document.querySelector('.site_header__promo #timer-cont')) document.querySelector('.site_header__promo #timer-cont').remove();
        document.querySelector('.site_header__promo').insertAdjacentHTML('afterBegin', `
        <style>
            .site_header__promo { display:flex;place-content:baseline;place-items:end; }
            #timer-cont { cursor:pointer;user-select:none;display:inline-block;position:relative;clear:right;color:#bb0000;font-size:1.1vw;font-weight:bold;font-family:LED;height:70px;marargin-top:-55px; }
            #timer-title { display:inline-block;position:relative;min-width:64px;bottom:-13%;left:-10px }
            #timer-date { font-size:calc(15px + .5vw);font-weight:normal;color:${localStorage.TimerColor || "rgb(127 2 137)"};transition:all 1s;background:#fff;padding:5px;margin-left:-30px; }
        </style>
            <div id='timer-cont' title='Нажмите для изменения цвета таймера'>
                <span id='timer-title'><img src='${staticURL}/img/new_year_tree.png'></span>
                <span id='timer-date'></span>
            </div>
        `);
        document.querySelector('#timer-cont').addEventListener('click', function () {
            localStorage.TimerColor = 'rgb(' + Random(0, 255) + ',' + Random(0, 255) + ',' + Random(0, 255) + ')';
            document.querySelector('#timer-date').style.color = localStorage.TimerColor;
        });
    }

    return nye;
}

function app_icon(exts, cl, style) {
    const iconsPath = 'https://ss.uooio.keenetic.pro:50005/static/uo-tashtagol.kemobl.ru/img/icons'
    const icons_ext = {
        'pdf': `${iconsPath}/pdf-icon.png`,
        'doc': `${iconsPath}/doc-icon.png`,
        'docx': `${iconsPath}/docx-icon.png`,
        'xls': `${iconsPath}/xls-icon.png`,
        'xlsx': `${iconsPath}/xlsx-icon.png`,
        'ppt': `${iconsPath}/ppt-icon.png`,
        'pptx': `${iconsPath}/ppt-icon.png`,
        'zip': `${iconsPath}/zip-icon.png`,
        'rar': `${iconsPath}/rar-icon.png`,
        'rtf': `${iconsPath}/rtf-icon.png`
    }
        , links = document.querySelectorAll('a[href]');
    if (typeof exts === 'string') {
        exts = [exts]
    } else if (!Array.isArray(exts)) {
        console.warn('Нужно передать массив или строку!');
        return
    }
    if (links) {
        for (let i = 0; i < links.length; i++) {
            for (let q = 0; q < exts.length; q++) {
                if (check_link(links[i], exts[q])) {
                    if (icons_ext.hasOwnProperty(exts[q])) {
                        add_icon(links[i], get_icon_path(exts[q]), style, cl);
                    } else {
                        console.warn('Не найдена иконка для: ' + exts[q])
                    }
                }
            }
        }
    }
    function add_icon(lnk, icon, style, cl = 'doc-icon') {
        if (lnk && icon && !lnk.getElementsByClassName(cl).length) {
            style = style !== '' && style !== undefined ? style : 'height:22px;width:22px;position:relative;top:4px;right:3px;vertical-align:middle';
            icon = '<img class="' + cl + '" src="' + icon + '" style="' + style + '">';

            lnk.insertAdjacentHTML('afterBegin', icon);
        }
    }
    function check_link(lnk, ext) {
        if (lnk.classList.contains('doc-icon-off')) return false;
        return (lnk.href.toLowerCase().lastIndexOf('.' + ext.toLowerCase()) >= 0)
    }
    function get_icon_path(ext) {
        for (let i_ext in icons_ext) {
            if (i_ext == ext)
                return icons_ext[i_ext];
        }
    }
}

async function get_pdf_sign_info() {
    let api_ver = 1.1,
        baseURL = "https://pdfgsiapi.uooio.keenetic.pro:50001",
        moduleURL = `${baseURL}/api/${api_ver}/PDF/sign-info/sign-info.js?ver=1.4`,
        { PDFGSI } = await import(moduleURL);
    PDFGSI("constructor-documents-list-item__icon");
}

console.log('functions module loaded');
export { waiting_block, goHeadRequest, getDT, run_events, snowInit, salute, cheats, document_viewer, app_icon, newYear, get_pdf_sign_info }